<template>
  <div class="main" ref="ref_main">
    <div style="position: absolute;top: 0;left: 0;background-color: #FFFFFF;">
      <span style="color: red">红色代表 X 轴. </span>
      <span style="color: green">绿色代表 Y 轴. </span>
      <span style="color: blue">蓝色代表 Z 轴. </span>
    </div>
    <canvas ref="ref_three"/>
  </div>
</template>

<script setup lang="ts">
import {getCurrentInstance, onMounted, reactive, ref} from "vue";
import * as THREE from 'three'
// 导入轨道控制器
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
// 导入gui调试开发
import {GUI} from 'three/examples/jsm/libs/lil-gui.module.min.js'
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';

let scene: any = null
const {proxy} = getCurrentInstance()
const state: any = reactive({
  animate: true,
  controlData: {
  },
  camera: null,
  renderer: null,
})
const ref_three = ref()
const ref_main = ref()
const initGUI = () => {
  // 创建GUI
  const gui = new GUI();
  // gui.add(state.controlData,"number", 0.01, 1, 0.01)
  gui.domElement.id = 'cus-gui'
  ref_main.value.appendChild(gui.domElement)
}
const initScene = () => {
  // 场景
  scene = new THREE.Scene();
  // scene.background = new THREE.Color('rgba(224,110,110,0.3)');
  state.bgCubeTexture = new THREE.CubeTextureLoader().setPath(import.meta.env.BASE_URL + 'src/views/three/test/' ).load( [
    'bg_2.jpeg',
    'bg_2.jpeg',
    'bg_2.jpeg',
    'bg_2.jpeg',
    'bg_2.jpeg',
    'bg_2.jpeg',
  ] );  //  确保你加载或创建的每个cubemap面的宽度和高度完全相同
  scene.background = state.bgCubeTexture
  // 摄像机
  state.camera = new THREE.PerspectiveCamera( 75, ref_three.value.clientWidth / ref_three.value.clientHeight, 0.1, 1000 );
  state.camera.position.x = 15
  state.camera.position.y = 15
  state.camera.position.z = -15
  // 渲染器
  state.renderer = new THREE.WebGLRenderer({ canvas: ref_three.value, antialias: true });
  state.renderer.setSize(ref_three.value.clientWidth, ref_three.value.clientHeight);
  state.renderer.shadowMap.enabled = true
  // 为了更清晰的看到物体的运动轨迹，可以添加坐标轴辅助对象AxesHelper
  // 红色代表 X 轴. 绿色代表 Y 轴. 蓝色代表 Z 轴.
  const axesHelper = new THREE.AxesHelper(10);
  scene.add(axesHelper);
  const cameraHelper = new THREE.CameraHelper( state.camera );
  scene.add(cameraHelper)

  // 监听窗口的变化
  window.addEventListener('resize',()=>{
    // 重置渲染器宽高比
    state.renderer.setSize(ref_three.value.clientWidth, ref_three.value.clientHeight);
    // 重置相机宽高比
    state.camera.aspect = ref_three.value.clientWidth / ref_three.value.clientHeight
    // 更新相机投影矩阵
    state.camera.updateProjectionMatrix()
  });

  initCube()
  initLight()
}
const initCube = () => {
// Instantiate a loader
  const loader = new GLTFLoader();
// Load a glTF resource
  loader.load(import.meta.env.BASE_URL + 'src/views/three/test/low_poly_accommodations_buildings.glb', (gltf) => {
      scene.add( gltf.scene );
      console.log(gltf)
    }, (xhr) => {
      console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
    }, (error) => {
      console.log( 'An error happened' );
    }
  )

  initAnimate()
}
const initLight = () => {
  const light2 = new THREE.PointLight('#ffffff', 3000);
  light2.power = 5000
  light2.position.set(10, 5, 5)
  light2.castShadow = true
  scene.add(light2)
  // 添加灯光辅助
  scene.add(new THREE.PointLightHelper(light2, 1))

  const light3 = new THREE.PointLight('#ffffff', 150);
  light3.power = 5000
  light3.position.set(10, 5, -5)
  light3.castShadow = true
  scene.add(light3)
  scene.add(new THREE.PointLightHelper(light3, 1))
}
const initAnimate = () => {
  // 添加OrbitControls来控制摄像机
  const controls = new OrbitControls(state.camera, state.renderer.domElement);
  //设置一些属性
  controls.enableDamping  = true //启用阻尼（惯性）
  controls.dampingFactor = 0.05 //阻尼惯性有多大
  controls.autoRotate = false // 自动旋转
  controls.autoRotateSpeed = 1.0 //围绕目标旋转的速度将有多快

  const animate = () => {
    if (state.animate) {
      //注意：以上属性设置后，必须再动画循环里面调用update()更新控制器
      controls.update()
      requestAnimationFrame(animate)
      state.renderer?.render( scene, state.camera );
    } else {
      state.renderer?.render( scene, state.camera );
    }
  }
  animate()
}
onMounted(() => {
  initGUI()
  initScene()
})
</script>

<style lang="scss" scoped>
.main {
  width: 100%;
  height: 100%;
  position: relative;
  :deep(#cus-gui) {
    position: absolute;
    z-index: 22;
    top: 0;
    right: 0;
  }
  >canvas {
    width: 100%;
    height: 100%;
  }
}
</style>
